package fu.capstone.hanoicityguide.presentation.fragment.nearby;

import java.util.ArrayList;
import org.mapsforge.core.model.LatLong;
import org.mapsforge.map.android.view.MapView;
import org.mapsforge.map.layer.Layers;
import org.mapsforge.map.layer.overlay.Marker;
import fu.capstone.hanoicityguide.R;
import fu.capstone.hanoicityguide.business.bo.nearbyplace.NearbyPlaceBO;
import fu.capstone.hanoicityguide.business.bo.nearbyplace.NearbyPlaceBOImp;
import fu.capstone.hanoicityguide.business.model.Place;
import fu.capstone.hanoicityguide.common.offlinemapultility.OfflineMapUtil;
import fu.capstone.hanoicityguide.common.utility.LocationSetting;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

@SuppressLint("ValidFragment")
public class NearbyOfflineMapFragment extends Fragment {

	private OfflineMapUtil util;
	private MapView mapview;
	private LocationSetting locationSetting;
	private MyLocationListener locationListener;
	private NearbyPlaceBO nearbyBO;
	private ArrayList<Place> arrNearby;
	private LatLong nearbyplace_geo;
	private Layers layers;
	private String keyword;
	private ArrayList<String> filter;
	private String sorter;

	public NearbyOfflineMapFragment(String keyword, ArrayList<String> filter,
			String sorter) {
		this.keyword = keyword;
		this.filter = filter;
		this.sorter = sorter;
	}

	public String getKeyword() {
		return this.keyword;
	}

	public ArrayList<String> getFilter() {
		return this.filter;
	}

	public String getSorter() {
		return this.sorter;
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		View nearbyOfflineMapFragment = inflater.inflate(
				R.layout.offline_map_fragment, container, false);
		util = new OfflineMapUtil(container.getContext());

		try {
			mapview = (MapView) nearbyOfflineMapFragment
					.findViewById(R.id.mapView);

			locationSetting = new LocationSetting(container.getContext());
			if (!locationSetting.getGPSSetting(container.getContext())) {
				locationSetting.showSettingsAlert();
			} else {
				util.setupofflinemap(mapview, container.getContext());
				String provider;
				LocationManager locManager = (LocationManager) container
						.getContext()
						.getSystemService(Context.LOCATION_SERVICE);
				locationListener = new MyLocationListener();
				locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
						1, 1, locationListener);

				Criteria criteria = new Criteria();
				provider = locManager.getBestProvider(criteria, false);
				Location lastKnownLoc = null;

				lastKnownLoc = locManager.getLastKnownLocation(provider);
				// GeoPoint currentLocation = new
				// GeoPoint(lastKnownLoc.getLatitude(),
				// lastKnownLoc.getLongitude());

				nearbyBO = new NearbyPlaceBOImp(container.getContext());
				arrNearby = nearbyBO.listNearbyPlace(
						lastKnownLoc.getLatitude(),
						lastKnownLoc.getLongitude(), 1000, getKeyword(),
						getFilter(), getSorter());

				// compare to radius, remove outer points
				if (arrNearby.size() != 0) {
					for (int i = 0; i < arrNearby.size(); i++) {
						Location tempLocation = new Location("TempLocation "
								+ i);
						tempLocation.setLatitude(arrNearby.get(i).getGeo()
								.getLatitude());
						tempLocation.setLongitude(arrNearby.get(i).getGeo()
								.getLongitude());

						double distance = tempLocation.distanceTo(lastKnownLoc);
						if (distance > 1000) {
							arrNearby.remove(i);
						}
					}
				}

				if (arrNearby.size() == 0 || arrNearby == null) {
					AlertDialog.Builder alertDialog = new AlertDialog.Builder(
							container.getContext());
					alertDialog.setTitle("Nearby Places");
					alertDialog.setMessage("Sorry! No nearby place detected");
					alertDialog.setNegativeButton("OK", new OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							// TODO Auto-generated method stub
							dialog.cancel();
						}
					});
				}

				layers = this.mapview.getLayerManager().getLayers();

				for (int i = 0; i < arrNearby.size(); i++) {
					nearbyplace_geo = util
							.convertGeoCoordinateToLatLong(arrNearby.get(i)
									.getGeo());
					Marker tempMarker = util.createMarker(container
							.getContext(), nearbyplace_geo, arrNearby.get(i)
							.getName(), arrNearby.get(i).getType());
					layers.add(tempMarker);
				}

			}
		} catch (Exception e) {
			Log.e("Nearby Fragment", e.toString());
		}
		return nearbyOfflineMapFragment;
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		LocationManager locManager = (LocationManager) getActivity()
				.getSystemService(Context.LOCATION_SERVICE);
		locManager.removeUpdates(locationListener);
		locManager = null;
	}

	public class MyLocationListener implements LocationListener {

		@Override
		public void onLocationChanged(Location location) {
			// TODO Auto-generated method stub

			layers.clear();

			util.setupofflinemap(mapview, getActivity());
			String provider;
			LocationManager locManager = (LocationManager) getActivity()
					.getSystemService(Context.LOCATION_SERVICE);
			Criteria criteria = new Criteria();
			provider = locManager.getBestProvider(criteria, false);
			Location lastKnownLoc = null;
			try {
				lastKnownLoc = locManager.getLastKnownLocation(provider);
				// GeoPoint currentLocation = new
				// GeoPoint(lastKnownLoc.getLatitude(),
				// lastKnownLoc.getLongitude());
			} catch (NullPointerException e) {
				Log.e("Nearby Fragment", e.toString());
			}

			nearbyBO = new NearbyPlaceBOImp(getActivity());
			arrNearby = nearbyBO.listNearbyPlace(lastKnownLoc.getLatitude(),
					lastKnownLoc.getLongitude(), 1000, getKeyword(),
					getFilter(), getSorter());

			// compare to radius, remove outer points
			if (arrNearby.size() != 0) {
				for (int i = 0; i < arrNearby.size(); i++) {
					Location tempLocation = new Location("TempLocation " + i);
					tempLocation.setLatitude(arrNearby.get(i).getGeo()
							.getLatitude());
					tempLocation.setLongitude(arrNearby.get(i).getGeo()
							.getLongitude());

					double distance = tempLocation.distanceTo(lastKnownLoc);
					if (distance > 1000) {
						arrNearby.remove(i);
					}
				}
			}

			if (arrNearby.size() == 0 || arrNearby == null) {
				AlertDialog.Builder alertDialog = new AlertDialog.Builder(
						getActivity());
				alertDialog.setTitle("Nearby Places");
				alertDialog.setMessage("Sorry! No nearby place detected");
				alertDialog.setNegativeButton("OK", new OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						dialog.cancel();
					}
				});
			}

			layers = mapview.getLayerManager().getLayers();

			for (int i = 0; i < arrNearby.size(); i++) {
				nearbyplace_geo = util.convertGeoCoordinateToLatLong(arrNearby
						.get(i).getGeo());
				Marker tempMarker = util.createMarker(getActivity(),
						nearbyplace_geo, arrNearby.get(i).getName(), arrNearby
								.get(i).getType());
				layers.add(tempMarker);
			}
		}

		@Override
		public void onProviderDisabled(String provider) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onProviderEnabled(String provider) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
			// TODO Auto-generated method stub

		}

	}
}
